#ifndef GC_HEADER
#define GC_HEADER
template <class itemType>
class GC {
	
	/* Private declaration of class members. */
	private:
		itemType* ptr;
		int* count;
	
	/* Private definition of member methods. */
	private:
		void increment (void){
			if (ptr == 0) return;
			++(*count);
		}

		void decrement (void){
			if (ptr == 0) return;
			if (--(*count) == 0){
				delete count;
				delete ptr;
			}
		}
	
	/* Public definition of member methcods. */
	public:		
		/* Constructor: Default one. */
		GC (void) : ptr(0), count(0){ }
		
		/* Explicit Copy Constructor: From pointer. */
		explicit GC (itemType* p) : ptr(p){ count = (p == 0) ? 0 : new int(1); }
		
		/* Copy Constructor: Copy from other GC. */
		GC (const GC<itemType>& src) : ptr(src.ptr), count(src.count){ increment(); }
		
		/* Destructor. */
		~GC (void)	{ decrement(); }
		
		/* Assignment operator=: From other GC. */
		GC<itemType>& operator= (const GC<itemType>& rhs){
			if (rhs.ptr == ptr) return *this;
			decrement();
			ptr = rhs.ptr;
			count = rhs.count;
			increment();
			return *this;
		}
		
		/* Assignment operator=: From pointer. */
		GC<itemType>& operator= (itemType* rhs){
			if (rhs == ptr) return *this;
			decrement();
			ptr = rhs;
			count = (ptr == 0) ? 0 : new int(1);
			return *this;
		}
		
		/* Operations. */
		void reset (void){
			decrement();
			ptr = 0; count = 0;
		}

		void swap (GC<itemType>& p){
			itemType* tp = p.ptr; p.ptr = ptr; ptr = tp;
			int *tc = p.count; p.count = count; count = tc;
		}
		
		/* Dereference. */
		itemType& operator* (void) const { return *ptr; }
		
		itemType* operator-> (void) const { return ptr; }
		
		/* Comparison. */
		bool operator== (const itemType* p) const { return p == ptr; }
		
		bool operator== (const GC<itemType>& p) const { return p.ptr == ptr; }
		
		bool operator!= (const itemType* p) const { return p != ptr; }
		
		bool operator!= (const GC<itemTypeT>& p) const { return p.ptr != ptr; }
		
		bool operator< (const GC<itemType>& rhs) { return ptr < rhs.ptr; }
		
		/* Information. */
		int use count (void) const	{ return (count == 0) ? 0 : *count; }
		itemType* get (void) const	{ return ptr; }
	#ifndef NO MEMBER TEMPLATES
		
	/* Template friends for accessing diffrent GC's. */
	private:
		template <class friendType> friend class GC;
	
	public:
		/* Constructor: From diffrent pointer. */
		template <class friendsType>
		explicit GC (friendType* p) : ptr(p)	{ count = (p == 0) ? 0 : new int(1); }
		
		/* Constructor: Copy from diffrent GC. */
		template <class friendType>
		GC (const GC<Y>& src) : ptr(src.ptr), count(src.count)	{ increment(); }
		
		/* Assignment: From diffrent GC. */
		template <class friendType>
		GC<itemType>& operator= (const GC<friendType>& rhs){
			if (rhs.ptr == ptr) return *this;
			decrement();
			ptr = rhs.ptr;
			count = rhs.count;
			increment();
			return *this;
		}
		
		/* Assignment: From diffrent pointer. */
		template <class friendType>
		GC<itemType>& operator= (friendType* rhs){
			if (rhs == ptr) return *this;
			decrement();
			ptr = rhs;
			count = (ptr == 0) ? 0 : new int(1);
			return *this;
		}
		
		/* Comparison with diffrent GC type. */
		template <class friendType>
		bool operator== (const GC<friendType>& p) const	{ return p.ptr == ptr; }
		
		template <class friendType>
		bool operator!= (const GC<friendType>& p) const	{ return p.ptr != ptr; }
		
		template <class friendType>
		bool operator< (const GC<friendType>& rhs) const	{ return ptr < rhs.ptr; }
	
	#endif /* NO MEMBER TEMPLATES */
};
#endif /* GC HEADER */